package com.zhoug.common.media.screenrecord;

import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.graphics.Point;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;


import com.zhoug.common.utils.AppUtils;
import com.zhoug.common.utils.LogUtils;
import com.zhoug.common.utils.ResourceUtils;

import java.util.Random;

import androidx.annotation.RequiresApi;
import androidx.fragment.app.Fragment;

/**
 * 屏幕录制
 *
 * @Author 35574
 * @Date 2020/5/5
 * @Description
 */
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class Recorder {
    private static final String TAG = ">>>Recorder";
    private MediaProjectionManager _mediaProjectionManager;
    private MediaProjection mMediaProjection;
    private VirtualDisplay mVirtualDisplay;
    private Fragment fragment;
    private Activity activity;
    private static int REQUEST_CODE = 2161;
    private String path;
    private Handler mainHandler = new Handler(Looper.getMainLooper());
    private MediaRecorder mMediaRecorder;
    private OnRecordStatusListener onRecordStatusListener;
    private final int FRAME_RATE = 25;//帧
    private final int bitRate = 1024 * 256;//视频清晰度 bit/秒

    private int width = 720;
    private int height = 1280;

    private boolean recording = false;

    public Recorder(Fragment fragment) {
        this.fragment = fragment;
        this.activity = fragment.getActivity();
        REQUEST_CODE = new Random().nextInt(5000) + 1000;
    }

    public Recorder(Activity activity) {
        this.activity = activity;
    }

    private MediaProjectionManager getMediaProjectionManager() {
        if (_mediaProjectionManager == null) {
            synchronized (this) {
                if (_mediaProjectionManager == null) {
                    _mediaProjectionManager = (MediaProjectionManager) activity.getSystemService(Service.MEDIA_PROJECTION_SERVICE);
                }
            }
        }
        return _mediaProjectionManager;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    /**
     * 开始录制
     */
    public void startRecord() {
        Point screenSize = AppUtils.getScreenSize();
        width = screenSize.x;
        height = screenSize.y;
        if (recording) {
            LogUtils.d(TAG, "startRecord:正在录制");
        } else {
            Intent captureIntent = getMediaProjectionManager().createScreenCaptureIntent();
            if (fragment != null) {
                fragment.startActivityForResult(captureIntent, REQUEST_CODE);
            } else {
                activity.startActivityForResult(captureIntent, REQUEST_CODE);
            }
        }

    }

    /**
     * 回掉
     *
     * @param requestCode
     * @param resultCode
     * @param data
     */
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CODE) {
            mMediaProjection = getMediaProjectionManager().getMediaProjection(resultCode, data);
            LogUtils.d(TAG, "onActivityResult:mMediaProjection=" + mMediaProjection);
            try {
                if (mMediaProjection != null) {
                    mMediaProjection.registerCallback(callback, mainHandler);
                    initMediaRecorder();
                    mVirtualDisplay = mMediaProjection.createVirtualDisplay("recorder", width, height,
                            ResourceUtils.getDisplayMetrics().densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,
                            mMediaRecorder.getSurface(), null, null);
                    mMediaRecorder.start();
                    recording = true;
                    LogUtils.d(TAG, "onActivityResult:开始录像");
                } else {
                    if (onRecordStatusListener != null) {
                        onRecordStatusListener.onStop();
                    }
                }
            } catch (IllegalStateException e) {
                e.printStackTrace();
                if (onRecordStatusListener != null) {
                    stopRecord();
                    onRecordStatusListener.onStop();
                }
            }
        }
    }

    private void initMediaRecorder() {
        try {
            if (mMediaRecorder == null) {
                mMediaRecorder = new MediaRecorder();
            }
            mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
            mMediaRecorder.setVideoFrameRate(FRAME_RATE);
            mMediaRecorder.setVideoEncodingBitRate(bitRate);
            mMediaRecorder.setVideoSize(width, height);
            mMediaRecorder.setOutputFile(path);
            int windowRotation = AppUtils.getWindowRotation();
            LogUtils.d(TAG, "initMediaRecorder:windowRotation=" + windowRotation);
//            mMediaRecorder.setOrientationHint(windowRotation);
            mMediaRecorder.prepare();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private MediaProjection.Callback callback = new MediaProjection.Callback() {
        @Override
        public void onStop() {
            super.onStop();
            if (onRecordStatusListener != null) {
                LogUtils.d(TAG, "onStop:");
                onRecordStatusListener.onStop();
            }
        }
    };


    public void stopRecord() {
        LogUtils.d(TAG, "stopRecord:停止录像");

        try {
            if (mVirtualDisplay != null) {
                mVirtualDisplay.release();
                mVirtualDisplay = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            if (mMediaProjection != null) {
                mMediaProjection.stop();
                mMediaProjection.unregisterCallback(callback);
                mMediaProjection = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            if (mMediaRecorder != null) {
                mMediaRecorder.stop();
//                mMediaRecorder.release();
                mMediaRecorder.reset();
                mMediaRecorder = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            if(mMediaRecorder!=null){
                mMediaRecorder.reset();
                mMediaRecorder = null;
            }
        }
        recording = false;

    }


    public void setOnRecordStatusListener(OnRecordStatusListener onRecordStatusListener) {
        this.onRecordStatusListener = onRecordStatusListener;
    }
}
